package com.yudean.esb.controller;

import com.yudean.esb.domain.mds.MdsERPFinIndex;
import com.yudean.esb.service.MdsERPFinIndexService;
import com.yudean.esb.security.SysAppUserService;
import com.yudean.esb.util.StringUtil;

import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Controller
@RequestMapping("erp/IndexService")
@Slf4j
public class ERPIndexServiceController {
    // 发电量
    private final static String ENERGY_CODE = "EP";
    // 净利润
    private final static String PROFIT_CODE = "NP";
    private final static String COMP_CODE = "SYSTEM";

    @Resource
    private SysAppUserService sysAppUserService;
    @Resource
    private MdsERPFinIndexService mdsERPFinIndexService;

    /**
     *
     *
     * @param compCode 公司三字码
     * @param userName 用户名
     * @param passwd   密码k
     * @return         获取去年的发电量
     */
    @GetMapping(value = "getLastYearEnergy", produces = "application/xml; charset=utf-8")
    @ResponseBody
    public String getLastYearEnergy(@RequestParam(value = "compCode", required = false) String compCode,
                                    @RequestParam(value = "userName") String userName,
                                    @RequestParam(value = "passwd") String passwd) {
        log.info("getLastYearEnergy-{}-{}", compCode, userName);
        return getLastYear(ENERGY_CODE, compCode, userName, passwd);
    }

    /**
     *
     *
     * @param compCode 公司三字码
     * @param userName 用户
     * @param passwd   密码
     * @return         获取公司今年的发电量
     */
    @RequestMapping(value = "getThisYearEnergy", produces = "application/xml; charset=utf-8")
    @ResponseBody
    public String getThisYearEnergy(@RequestParam(value = "compCode", required = false) String compCode,
                                    @RequestParam(value = "userName") String userName,
                                    @RequestParam(value = "passwd") String passwd) {
        log.info("getThisYearEnergy-{}-{}", compCode, userName);
        return getThisYear(ENERGY_CODE, compCode, userName, passwd);
    }

    /**
     *
     *
     * @param compCode 公司三字码
     * @param userName 用户名
     * @param passwd   密码
     * @return         获得去年的净利润
     */
    @RequestMapping(value = "getLastYearProfit", produces = "application/xml; charset=utf-8")
    @ResponseBody
    public String getLastYearProfit(@RequestParam(value = "compCode", required = false) String compCode,
                                    @RequestParam(value = "userName") String userName,
                                    @RequestParam(value = "passwd") String passwd) {
        log.info("getLastYearProfit-{}-{}", compCode, userName);
        return getLastYear(PROFIT_CODE, compCode, userName, passwd);
    }

    /**
     * @param compCode 公司三字码
     * @param userName 用户名
     * @param passwd   密码
     * @return         获得本年度的净利润
     */
    @GetMapping(value = "getThisYearProfit", produces = "application/xml; charset=utf-8")
    @ResponseBody
    public String getThisYearProfit(
            @RequestParam(value = "compCode", required = false) String compCode,
            @RequestParam(value = "userName") String userName,
            @RequestParam(value = "passwd") String passwd) {
        log.info("getThisYearProfit-{}-{}", compCode, userName);
        return getThisYear(PROFIT_CODE, compCode, userName, passwd);
    }

    private String getLastYear(String indexCode, String compCode,
                               String userName, String passwd) {
        if (!hasPermission(compCode, userName, passwd)) {
            return noPermission();
        }

        // 需要計算去年
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 1);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        String yearCode = sdf.format(calendar.getTime());
        //避免查询到数据为空，先到数据库中查询历史数据 //查询上一年已有数据中最大月份 add by szq
        String monthCode = "" + mdsERPFinIndexService.getLastMaxMonth(Integer.parseInt(yearCode));

        log.debug(
                "getLastYear():request-{indexCode：{},compCode:{},lastYear:{}}",
                indexCode, compCode, yearCode);

        MdsERPFinIndex bean = null;
        try {
            bean = buildBean(compCode, yearCode, monthCode);
        } catch (Exception e) {
            return noData();
        }

        bean.setIndexCode(indexCode);
        List<MdsERPFinIndex> list = mdsERPFinIndexService.findIndex(bean);
        return handleResultList(list);
    }

    private String getThisYear(String indexCode, String compCode,
                               String userName, String passwd) {
        if (!hasPermission(compCode, userName, passwd)) {
            return noPermission();
        }
        Date now = new Date();
        SimpleDateFormat yyyy = new SimpleDateFormat("yyyy");
        SimpleDateFormat MM = new SimpleDateFormat("MM");
        String yearCode = yyyy.format(now);
        String monthCode = MM.format(now);

        log.debug(
                "getThisYear():request-{indexCode:{},compCode:{},thisYear:{},thisMonth:{}}",
                indexCode, compCode, yearCode, monthCode);

        MdsERPFinIndex bean = null;
        try {
            bean = buildBean(compCode, yearCode, monthCode);
        } catch (Exception e) {
            return noData();
        }
        bean.setIndexCode(indexCode);
        List<MdsERPFinIndex> list = mdsERPFinIndexService.getThisYear(bean);
        return handleResultList(list);
    }

    /**
     * 验证是否拥有访问的权限
     *
     * @param compCode  公司
     * @param userName  用户名
     * @param passwd    密码
     * @return          boolean
     */
    private boolean hasPermission(String compCode, String userName, String passwd) {
        return sysAppUserService.hasPermit(COMP_CODE,userName, passwd);
    }

    /**
     * @return  权限认证失败返回的信息
     */
    private static String noPermission() {
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><service><name>ERP财务汇总信息</name><type>发布服务</type><datalist><!--权限认证失败--></datalist></service>";
    }

    /**
     * @return  返回空数据的时候的信息
     */
    private static String noData() {
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><service><name>ERP财务汇总信息</name><type>发布服务</type><datalist><!--查无数据--></datalist></service>";
    }


    /**
     * @param compCode  公司三字码
     * @param yearCode  年份代码
     * @param monthCode 月份代码
     * @return          将传入参数构造成一个bean
     */
    private MdsERPFinIndex buildBean(String compCode, String yearCode,
                                     String monthCode) throws IllegalArgumentException {
        MdsERPFinIndex bean = new MdsERPFinIndex();
        //根据输入，初始化compCode,yearCode,monthCode
        if (compCode == null || "".equals(compCode.trim())) {
            bean.setCompCode(null);
        } else {
            bean.setCompCode(compCode.trim());
        }

        if (yearCode == null || "".equals(yearCode.trim())) {
            bean.setPeriodYear(null);
        } else {
            Integer year = null;
            try {
                year = Integer.parseInt(yearCode.trim());

            } catch (Exception e) {
                log.error("buildBean():参数不合法-{yearCode:{}}", yearCode);
                throw new IllegalArgumentException();
            }
            bean.setPeriodYear(year);
        }

        if (monthCode == null || "".equals(monthCode.trim())) {
            bean.setPeriodMonth(null);
        } else {
            Integer month = null;
            try {
                month = Integer.parseInt(monthCode.trim());
            } catch (Exception e) {
                log.error("buildBean():参数不合法-{monthCode:{}}", monthCode);
                throw new IllegalArgumentException();
            }
            bean.setPeriodMonth(month);
        }
        return bean;
    }


    /**
     * @param list
     * @return  处理查询的结果集，包括对空集的处理
     */
    private String handleResultList(List<MdsERPFinIndex> list) {
        if (list == null || list.size() < 1) {
            log.debug("No Data!");
            return noData();
        }
        return parseERPFinIndexList(list);
    }

    /**
     * 转换List为XML字符串
     *
     * @param list
     * @return
     */
    private String parseERPFinIndexList(List<MdsERPFinIndex> list) {
        Document doc = null;
        doc = DocumentHelper.createDocument();
        Element root = doc.addElement("service");
        root.addElement("name").setText("ERP财务汇总信息");
        root.addElement("type").setText("发布服务");
        Element dataList = root.addElement("datalist");
        try {
            int size = list.size();
            for (int i = 0; i < size; i++) {
                MdsERPFinIndex finIndex = list.get(i);
                if (finIndex == null) {
                    continue;
                }
                Element data = dataList.addElement("data");
                this.dataWrapper(finIndex, data);
            }
            return doc.asXML();
        } catch (Exception e) {
            log.error("parseList():error:" + e.getMessage(), e);
            return noData();
        }
    }


    /**
     * 将对象装配到Elment中去
     *
     * @param index
     * @param data
     */
    private void dataWrapper(MdsERPFinIndex index, Element data) {
        data.addElement("compCode").setText(
                StringUtil.convertToString(index.getCompCode()));

        data.addElement("entityName").setText(
                StringUtil.convertToString(index.getEntityName()));

        data.addElement("eipName").setText(
                StringUtil.convertToString(index.getEipName()));

        data.addElement("periodYear").setText(
                StringUtil.convertToString(index.getPeriodYear()));

        data.addElement("periodMonth").setText(
                StringUtil.convertToString(index.getPeriodMonth()));

        data.addElement("periodName").setText(
                StringUtil.convertToString(index.getPeriodName()));

        data.addElement("indexCode").setText(
                StringUtil.convertToString(index.getIndexCode()));

        data.addElement("indexName").setText(
                StringUtil.convertToString(index.getIndexName()));

        data.addElement("indexValueYTD").setText(
                StringUtil.convertToString(index.getIndexValueYTD()));
    }
}